package com.xxl.rpc.remoting.net.impl.jetty.server;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

import com.xxl.rpc.remoting.net.Server;
import com.xxl.rpc.remoting.provider.XxlRpcProviderFactory;

/**
 * jetty server = jetty服务
 * 
 * @author xuxueli 2015-11-19 22:29:03
 */
public class JettyServer extends Server {

	private org.eclipse.jetty.server.Server server;
	private Thread thread;

	/**
	 * JettyServer启动
	 * 
	 * @see com.xxl.rpc.remoting.net.Server#start(com.xxl.rpc.remoting.provider.XxlRpcProviderFactory)
	 */
	@Override
	public void start(final XxlRpcProviderFactory xxlRpcProviderFactory) throws Exception {

		thread = new Thread(new Runnable() {

			@Override
			public void run() {

				// The Server
				server = new org.eclipse.jetty.server.Server(new QueuedThreadPool()); // default maxThreads 200,
																						// minThreads 8
				// TODO, thread config, change to async servlet

				// HTTP connector
				ServerConnector connector = new ServerConnector(server);
				/*
				 * if (ip!=null && ip.trim().length()>0) { // TODO, support set registry ip、and bind ip
				 * //connector.setHost(ip); // The network interface this connector binds to as an IP address or a
				 * hostname. If null or 0.0.0.0, then bind to all interfaces. }
				 */
				connector.setPort(xxlRpcProviderFactory.getPort());
				server.setConnectors(new Connector[] { connector });

				// Set a handler
				HandlerCollection handlerc = new HandlerCollection();
				// 设置一个处理器JettyServerHandler
				handlerc.setHandlers(new Handler[] { new JettyServerHandler(xxlRpcProviderFactory) });
				server.setHandler(handlerc);

				try {
					server.start();

					logger.info(">>>>>>>>>>> xxl-rpc remoting server start success, nettype = {}, port = {}",
							JettyServer.class.getName(), xxlRpcProviderFactory.getPort());
					onStarted();

					server.join();
				} catch (Exception e) {
					logger.error(">>>>>>>>>>> xxl-rpc remoting server start error.", e);
				} finally {
					try {
						stop();
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
		});
		thread.setDaemon(true); // daemon, service jvm, user thread leave >>> daemon leave >>> jvm leave
		thread.start();
	}

	@Override
	public void stop() throws Exception {

		// destroy server
		if (server != null && server.isRunning()) {
			try {
				server.stop();
				server.destroy();
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
		if (thread != null && thread.isAlive()) {
			thread.interrupt();
		}

		onStoped();
		logger.info(">>>>>>>>>>> xxl-rpc remoting server destroy success.");
	}
}
